package cn.yanjr.common.web;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import cn.yanjr.common.Constant;

/**<br> * 这里使用的是Servlet的3.0注解式开发！<br> */
public class BaseServlet extends HttpServlet {
	private static Logger logger = Logger.getLogger(BaseServlet.class);
	/*
	 * 它会根据请求中的m，来决定调用本类的哪个方法
	 */
//	@SuppressWarnings({ "unchecked", "rawtypes" })
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//--------------------------------------------处理编码-------------------------------------------------
		 
		// 如果是以get方式提交，交由GetServlet进行处理！
        if(request.getMethod().equalsIgnoreCase("get")){
        	request = new GetServlet(request);
        }else{// 这里则是以Post方式进行提交的结果
        	request.setCharacterEncoding(Constant.DEFAULT_CHARSET);
        }
        response.setCharacterEncoding(Constant.DEFAULT_CHARSET);
        logger.info(request.getContentType());
        
	//---------------------------------------------------------------------------------------------
        // 1. 获取访问地址的uri
        String uri = request.getRequestURI();
        // 2. 获取uri最后一个斜线的位置：找到uri中最后 一个斜线的位置
        int currentPosition = uri.lastIndexOf('/');
        // 3. 获取方法名称：截取uri中最后一个斜线 之后的单词 注意：substring方法是包含开头、但是不包含结尾，故而在原有的位置之上进行加1操作
        String methodName = uri.substring(currentPosition + 1);
        logger.info("BaseServlet: methodName=" + methodName);
        // 4. 谁继承BaseServlet、并且调用了BaseServlet,谁就是this
        Class<? extends BaseServlet> clazz = this.getClass();
        
        
        // 当没用指定要调用的方法时，那么默认请求的是execute()方法。
		if(methodName == null || methodName.isEmpty()) {
			methodName = "execute";
		}
		try {
			// 5. 通过反射机制拿到的clazz(调用对象) 进行忽略访问权限进而获取clazz中的方法，参数为方法名称，请求对象、响应对象
			Method m = clazz.getDeclaredMethod(methodName, HttpServletRequest.class,
					HttpServletResponse.class);
			Type type = m.getAnnotatedReturnType().getType();
			if(!"void".equals(type.getTypeName())) {
				// 6. 获取调用的返回值 并且通过invoke方法执行调用业务方法
				String result = (String) m.invoke(this, request, response);
				// 通过返回值完成请求转发
				// 判断 转发页面中是否包含 冒号、用于判断继承类中是否写入了  forward或者是redirect  ，有冒号，则表示写入了！
				if(result.contains(":")){
					String[] datas = result.split(":");
					logger.info("分隔后第一个数据"+datas[0] + "分隔后第二个数据"+datas[1]);
					if("forward".equals(datas[0])){
						// 8. 根据接受到的界面进行转发！
						request.getRequestDispatcher(datas[1]+".jsp").forward(request, response);
					} else if("redirect".equals(datas[0])){
						response.sendRedirect(request.getContextPath() + datas[1] + ".jsp");
					}
				}
				response.setContentType("text/html;charset=utf-8");
			} else {
				m.invoke(this, request, response);
				response.setContentType("application/json;charset=utf-8");
			}
		} catch (Exception e) {
			logger.error("BaseServlet有异常!..........................", e);
			throw new ServletException(e);
		}
	}
}
